package com.huxuesong.prcc.config;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huxuesong.prcc.dto.UmsMemberTransferInfoDTO;
import com.huxuesong.prcc.pojo.TokenTransaction;
import com.huxuesong.prcc.pojo.TokenTransactionResponse;
import com.huxuesong.prcc.ums.entity.UmsCoinAddress;
import com.huxuesong.prcc.ums.entity.UmsMember;
import com.huxuesong.prcc.ums.entity.UmsMemberTransferInfo;
import com.huxuesong.prcc.ums.mapper.UmsMemberMapper;
import com.huxuesong.prcc.ums.mapper.UmsMemberTransferInfoMapper;
import com.huxuesong.prcc.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@EnableScheduling
@Slf4j
public class ChargeTask {

    @Autowired
    UmsMemberMapper umsMemberMapper;

    @Autowired
    UmsMemberTransferInfoMapper umsMemberTransferInfoMapper;
    // 五分钟做一次轮询
    @Scheduled(fixedDelay = 1000*60*5)
    public void queryCharge() throws InterruptedException {
        List<UmsMember> UmsMembers = umsMemberMapper.selectList(new QueryWrapper<>());
        for (UmsMember member: UmsMembers) {
            if(StringUtils.isEmpty(member.getCoinAddress())){
                continue;
            }
            this.getTokenTransactionsHistory("0x4B851129d3d7C34d1d15E46B137861dAf5414523",member);
            Thread.sleep(1000);
        }
//        checkPrccLockToYuanbao();
    }

    // 每天定时凌晨1点开始跑任务检查一周前的prccLockToYuanbao
    @Scheduled(cron = "0 0 1 * * ?")
    public void checkPrccLockToYuanbao(){


        List<UmsMemberTransferInfo> umsMemberTransferInfos = umsMemberTransferInfoMapper.selectList(
                new QueryWrapper<UmsMemberTransferInfo>()
                        .eq("status",0)
                        .eq("transfer_type",UmsMemberTransferInfoDTO.UNLOCK_PRCC)
                        .between("begin_time", DateUtils.addDay(DateUtils.getTodayStartTime(),-7),DateUtils.addDay(DateUtils.getTodayEndTime(),-7))
        );

        for (UmsMemberTransferInfo umsMemberTransferInfo:umsMemberTransferInfos) {

            UmsMember member = getByUsername(umsMemberTransferInfo.getUserName());

            member.setTreePrcc(member.getTreePrcc().add(umsMemberTransferInfo.getTreePrcc()));
            member.setYuanbao(member.getYuanbao().add(umsMemberTransferInfo.getYuanbao()));

            umsMemberTransferInfo.setStatus(1);
            umsMemberTransferInfo.setResMsg("完成");
            umsMemberTransferInfo.setEndTime(LocalDateTime.now(ZoneOffset.of("+8")));

            umsMemberTransferInfoMapper.updateById(umsMemberTransferInfo);
            umsMemberMapper.updateById(member);
        }
    }

    public UmsMember getByUsername(String username) {
        UmsMember umsMember = new UmsMember();
        umsMember.setUsername(username);


        umsMember = umsMemberMapper.selectOne(new QueryWrapper<>(umsMember));


        return umsMember;
    }



    private TokenTransactionResponse getTokenTransactionsHistory(String contractAddress,UmsMember member) {
//        0x4B851129d3d7C34d1d15E46B137861dAf5414523

        final String url = "https://api.etherscan.io/api?module={module}&action={action}&contractaddress={contractaddress}&address={address}&startblock={startblock}&endblock={endblock}&sort={sort}";

        Map<String, String> params = new HashMap<String, String>();
        params.put("module", "account");
        params.put("action", "tokentx");
        params.put("contractaddress",contractAddress);
        params.put("address", member.getCoinAddress());
        params.put("startblock", String.valueOf(member.getLastBlockNumber()+1));
        params.put("endblock", String.valueOf(99999999));
        params.put("sort", "asc");
//        params.put("apikey", "RT5JW37AKEZVSW3C91Z86IGI2FF7JDPF1N");
        RestTemplate restTemplate = new RestTemplate();
        TokenTransactionResponse result = restTemplate.getForObject(url, TokenTransactionResponse.class, params);


        for (TokenTransaction transaction :result.getResult()) {

            String createTimeStamp = member.getCreateTime().atZone(ZoneOffset.UTC).toEpochSecond()+"";
            if(transaction.getTimeStamp().compareTo(createTimeStamp)<0){
                log.info("hxs:"+transaction.getTimeStamp()+" "+createTimeStamp+" "+member.getCreateTime());
                continue;
            }
            log.info(transaction.toString());
            if(transaction.getTokenSymbol().equals("PRCC")) {
                member.setLastBlockNumber(transaction.getBlockNumber());
                BigDecimal chargePrcc = new BigDecimal(transaction.getValue()).divide(new BigDecimal(100000000));
                BigDecimal curPrcc = member.getPrcc().add(chargePrcc);
                member.setPrcc(curPrcc);
                UmsMemberTransferInfo transferInfo = new UmsMemberTransferInfo();
                transferInfo.setUserName(member.getUsername());
                transferInfo.setToAddress(transaction.getTo());
                transferInfo.setFromAddress(transaction.getFrom());
                transferInfo.setPrcc(chargePrcc);
                transferInfo.setBeginTime(LocalDateTime.now(ZoneOffset.of("+8")));
                transferInfo.setTransferType(UmsMemberTransferInfoDTO.INNER_TRANSFER_PRCC);
                transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.INNER_TRANSFER_PRCC_STR);
                transferInfo.setBlockNumber(transaction.getBlockNumber());
                transferInfo.setHash(transaction.getHash());
                transferInfo.setEndTime(LocalDateTime.now(ZoneOffset.of("+8")));
                transferInfo.setRecvCoinAddress(transaction.getTo());
                transferInfo.setStatus(1);
                transferInfo.setResMsg("充值完成");
                umsMemberTransferInfoMapper.insert(transferInfo);
                umsMemberMapper.updateById(member);
            }
        }
        return result;
    }
}
